import os
import pathlib
import time

from appium.options.common import AppiumOptions
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from appium.webdriver.webdriver import WebDriver
from selenium.common import NoSuchElementException


class Base:
    __IMPLICITLY_WAIT_TIME = 10
    __APP_PACKAGE = "com.tencent.wework"

    def __init__(self, driver: WebDriver = None):
        if driver is None:
            self.driver_connect()
        else:
            self.driver = driver

    def driver_connect(self):
        caps = {}
        # 设置 app 安装平台
        caps["appium:platformName"] = "Android"
        # 设置 app 安装平台的版本
        # caps["appium:platformVersion"] = "6"
        # 设备的名字
        caps["appium:deviceName"] = "RPG0218A23005608"
        # 设置 app 的包名
        caps["appium:appPackage"] = "com.tencent.wework"
        # 设置 app 启动页
        caps["appium:appActivity"] = ".launch.LaunchSplashActivity"
        # 不清空缓存
        caps["appium:noReset"] = True
        # 实例化 appiumOptions 对象
        options = AppiumOptions().load_capabilities(caps)
        # os.system('start cmd /k appium')
        # 连接 appium server
        self.driver = webdriver.Remote("http://localhost:4723/wd/hub", options=options)
        # 设置全局的隐式等待
        self.driver.implicitly_wait(self.__IMPLICITLY_WAIT_TIME)
        return self

    def swipe_window(self):
        '''
        滑动界面
        '''
        # 滑动操作
        # 获取设备的尺寸
        size = self.driver.get_window_size()
        # {"width": xx, "height": xx}
        print(f"设备尺寸为 {size}")
        width = size.get("width")
        height = size.get('height')
        # # 获取滑动操作的坐标值
        start_x = width / 2
        start_y = height * 0.8
        end_x = start_x
        end_y = height * 0.2
        # swipe(起始x坐标，起始y坐标，结束x坐标，结束y坐标，滑动时间（单位毫秒）)
        self.driver.swipe(start_x, start_y, end_x, end_y, 2000)

    def swipe_find(self, text, max_num=5):
        '''
        滑动查找
        通过文本来查找元素，如果没有找到元素，就滑动，
        如果找到了，就返回元素
        '''
        # 为了滑动操作更快速，不用等待隐式等待设置的时间
        self.driver.implicitly_wait(1)
        for num in range(max_num):
            try:
                # 正常通过文本查找元素
                ele = self.driver.find_element(AppiumBy.XPATH, f"//*[@text='{text}']")
                print("找到元素")
                # 能找到则把隐式等待恢复原来的时间
                self.driver.implicitly_wait(10)
                # 返回找到的元素对象
                return ele
            except Exception:
                # 当查找元素发生异常时
                print(f"没有找到元素，开始滑动")
                print(f"滑动第{num + 1}次")
                # 滑动操作
                self.swipe_window()
        # 把隐式等待恢复原来的时间
        self.driver.implicitly_wait(10)
        # 抛出找不到元素的异常
        raise NoSuchElementException(f"滑动之后，未找到 {text} 元素")

    def screenshot(self):
        '''
        截图
        :param path: 截图保存路径
        '''
        root_path = pathlib.Path(__file__).parent
        cur_time = time.strftime("%Y-%m-%d-%H-%M-%S")
        file_path = cur_time + ".png"
        dir_path = root_path / 'screenshot'
        # 资源目录如果不存在则新创建一个
        if not os.path.isdir(dir_path):
            os.mkdir(dir_path)
        # 截图保存路径
        source_path = dir_path / file_path
        # 截图
        self.driver.save_screenshot(source_path)
        # 返回保存图片的路径
        return source_path

    def find_ele(self, by, value=None):
        if value is None:
            ele = self.driver.find_element(*by)
        else:
            ele = self.driver.find_element(by, value)
        return ele

    def find_eles(self, by, value=None):
        if value is None:
            eles = self.driver.find_elements(*by)
        else:
            eles = self.driver.find_elements(by, value)
        return eles

    def return_main(self):
        # self.driver.execute_script('mobile:startActivity',
        #                            {"app_package": "com.tencent.wework",
        #                             "app_activity": ".launch.LaunchSplashActivity"})
        for i in range(0, 5):
            self.back()
        self.driver.activate_app(self.__APP_PACKAGE)

    def quit(self):
        self.driver.quit()

    def back(self):
        self.driver.back()
